#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
插件系统 - 提升程序拓展性
"""

import os
import sys
import importlib
import inspect
from abc import ABC, abstractmethod
from typing import Dict, List, Any, Optional
from datetime import datetime

class PluginInterface(ABC):
    """
    插件接口
    
    所有插件都必须实现此接口
    """
    
    @abstractmethod
    def get_name(self) -> str:
        """获取插件名称"""
        pass
    
    @abstractmethod
    def get_version(self) -> str:
        """获取插件版本"""
        pass
    
    @abstractmethod
    def get_description(self) -> str:
        """获取插件描述"""
        pass
    
    @abstractmethod
    def initialize(self, context: Dict[str, Any]) -> bool:
        """
        初始化插件
        
        Args:
            context: 上下文信息，包含账单数据、配置等
            
        Returns:
            bool: 初始化是否成功
        """
        pass
    
    @abstractmethod
    def execute(self, data: Any) -> Any:
        """
        执行插件功能
        
        Args:
            data: 输入数据
            
        Returns:
            Any: 处理结果
        """
        pass
    
    def cleanup(self):
        """清理资源"""
        pass

class PluginManager:
    """
    插件管理器
    
    负责插件的加载、注册、执行和管理
    """
    
    def __init__(self, plugin_dir: str = "plugins"):
        """
        初始化插件管理器
        
        Args:
            plugin_dir: 插件目录
        """
        self.plugin_dir = plugin_dir
        self.plugins: Dict[str, PluginInterface] = {}
        self.plugin_configs: Dict[str, Dict[str, Any]] = {}
        self.ensure_plugin_dir()
        self.load_plugins()
    
    def ensure_plugin_dir(self):
        """确保插件目录存在"""
        if not os.path.exists(self.plugin_dir):
            os.makedirs(self.plugin_dir)
            # 创建__init__.py文件
            with open(os.path.join(self.plugin_dir, "__init__.py"), 'w') as f:
                f.write("# 插件目录\n")
    
    def load_plugins(self):
        """加载所有插件"""
        if not os.path.exists(self.plugin_dir):
            return
        
        for filename in os.listdir(self.plugin_dir):
            if filename.endswith('.py') and not filename.startswith('__'):
                plugin_name = filename[:-3]
                try:
                    self.load_plugin(plugin_name)
                except Exception as e:
                    print(f"加载插件 {plugin_name} 失败: {e}")
    
    def load_plugin(self, plugin_name: str) -> bool:
        """
        加载指定插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            bool: 加载是否成功
        """
        try:
            # 动态导入插件模块
            module_path = f"{self.plugin_dir}.{plugin_name}"
            if module_path in sys.modules:
                module = sys.modules[module_path]
            else:
                module = importlib.import_module(module_path)
            
            # 查找插件类
            plugin_class = None
            for name, obj in inspect.getmembers(module):
                if (inspect.isclass(obj) and 
                    issubclass(obj, PluginInterface) and 
                    obj != PluginInterface):
                    plugin_class = obj
                    break
            
            if plugin_class is None:
                print(f"插件 {plugin_name} 中没有找到有效的插件类")
                return False
            
            # 创建插件实例
            plugin_instance = plugin_class()
            
            # 注册插件
            self.register_plugin(plugin_instance)
            
            print(f"插件 {plugin_name} 加载成功")
            return True
            
        except Exception as e:
            print(f"加载插件 {plugin_name} 失败: {e}")
            return False
    
    def register_plugin(self, plugin: PluginInterface):
        """
        注册插件
        
        Args:
            plugin: 插件实例
        """
        plugin_name = plugin.get_name()
        self.plugins[plugin_name] = plugin
        print(f"插件 {plugin_name} 注册成功")
    
    def unregister_plugin(self, plugin_name: str):
        """
        注销插件
        
        Args:
            plugin_name: 插件名称
        """
        if plugin_name in self.plugins:
            self.plugins[plugin_name].cleanup()
            del self.plugins[plugin_name]
            print(f"插件 {plugin_name} 注销成功")
    
    def get_plugin(self, plugin_name: str) -> Optional[PluginInterface]:
        """
        获取插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            PluginInterface: 插件实例，如果不存在返回None
        """
        return self.plugins.get(plugin_name)
    
    def list_plugins(self) -> List[str]:
        """
        列出所有插件
        
        Returns:
            List[str]: 插件名称列表
        """
        return list(self.plugins.keys())
    
    def execute_plugin(self, plugin_name: str, data: Any) -> Any:
        """
        执行插件
        
        Args:
            plugin_name: 插件名称
            data: 输入数据
            
        Returns:
            Any: 处理结果
        """
        plugin = self.get_plugin(plugin_name)
        if plugin is None:
            raise ValueError(f"插件 {plugin_name} 不存在")
        
        return plugin.execute(data)
    
    def execute_all_plugins(self, data: Any) -> Dict[str, Any]:
        """
        执行所有插件
        
        Args:
            data: 输入数据
            
        Returns:
            Dict[str, Any]: 所有插件的执行结果
        """
        results = {}
        for plugin_name, plugin in self.plugins.items():
            try:
                result = plugin.execute(data)
                results[plugin_name] = result
            except Exception as e:
                print(f"执行插件 {plugin_name} 失败: {e}")
                results[plugin_name] = None
        
        return results
    
    def initialize_plugins(self, context: Dict[str, Any]):
        """
        初始化所有插件
        
        Args:
            context: 上下文信息
        """
        for plugin_name, plugin in self.plugins.items():
            try:
                success = plugin.initialize(context)
                if success:
                    print(f"插件 {plugin_name} 初始化成功")
                else:
                    print(f"插件 {plugin_name} 初始化失败")
            except Exception as e:
                print(f"初始化插件 {plugin_name} 失败: {e}")
    
    def cleanup_all_plugins(self):
        """清理所有插件"""
        for plugin in self.plugins.values():
            try:
                plugin.cleanup()
            except Exception as e:
                print(f"清理插件失败: {e}")

# 示例插件：数据统计插件
class DataStatisticsPlugin(PluginInterface):
    """数据统计插件"""
    
    def get_name(self) -> str:
        return "数据统计"
    
    def get_version(self) -> str:
        return "1.0.0"
    
    def get_description(self) -> str:
        return "提供账单数据统计分析功能"
    
    def initialize(self, context: Dict[str, Any]) -> bool:
        """初始化插件"""
        self.context = context
        return True
    
    def execute(self, data: Any) -> Any:
        """执行统计功能"""
        if not isinstance(data, list):
            return None
        
        # 统计收入支出
        total_income = sum(bill['amount'] for bill in data if bill['type'] == 'income')
        total_expense = sum(bill['amount'] for bill in data if bill['type'] == 'expense')
        total_neutral = sum(bill['amount'] for bill in data if bill['type'] == 'neutral')
        
        # 统计平台分布
        platform_stats = {}
        for bill in data:
            platform = bill['platform']
            if platform not in platform_stats:
                platform_stats[platform] = {'count': 0, 'amount': 0}
            platform_stats[platform]['count'] += 1
            platform_stats[platform]['amount'] += bill['amount']
        
        return {
            'total_income': total_income,
            'total_expense': total_expense,
            'total_neutral': total_neutral,
            'net_income': total_income - total_expense,
            'platform_stats': platform_stats,
            'total_records': len(data)
        }
    
    def cleanup(self):
        """清理资源"""
        pass

# 示例插件：数据导出插件
class DataExportPlugin(PluginInterface):
    """数据导出插件"""
    
    def get_name(self) -> str:
        return "数据导出"
    
    def get_version(self) -> str:
        return "1.0.0"
    
    def get_description(self) -> str:
        return "提供多种格式的数据导出功能"
    
    def initialize(self, context: Dict[str, Any]) -> bool:
        """初始化插件"""
        self.context = context
        self.supported_formats = ['excel', 'csv', 'json', 'pdf']
        return True
    
    def execute(self, data: Any) -> Any:
        """执行导出功能"""
        if not isinstance(data, list):
            return None
        
        export_info = {
            'supported_formats': self.supported_formats,
            'data_count': len(data),
            'export_time': datetime.now().isoformat(),
            'formats_available': True
        }
        
        return export_info
    
    def cleanup(self):
        """清理资源"""
        pass

# 使用示例
if __name__ == "__main__":
    # 创建插件管理器
    plugin_manager = PluginManager()
    
    # 手动注册示例插件
    stats_plugin = DataStatisticsPlugin()
    export_plugin = DataExportPlugin()
    
    plugin_manager.register_plugin(stats_plugin)
    plugin_manager.register_plugin(export_plugin)
    
    # 初始化插件
    context = {'config': {}, 'data': []}
    plugin_manager.initialize_plugins(context)
    
    # 模拟数据
    sample_data = [
        {'platform': 'alipay', 'type': 'income', 'amount': 100.0},
        {'platform': 'wechat', 'type': 'expense', 'amount': 50.0},
        {'platform': 'alipay', 'type': 'neutral', 'amount': 10.0}
    ]
    
    # 执行所有插件
    results = plugin_manager.execute_all_plugins(sample_data)
    
    print("插件执行结果:")
    for plugin_name, result in results.items():
        print(f"{plugin_name}: {result}")
    
    # 清理资源
    plugin_manager.cleanup_all_plugins()
    
    print("插件系统测试完成！")
